<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\Common\Service\BatchUpdateService;
use App\CustHub\Constants\OpSchemeTypeConstants;
use App\CustHub\Constants\RoomActiveRoomTypeConstants;
use App\CustHub\Mapper\ChOpSchemeMapper;
use App\CustHub\Mapper\ChRoomActiveRoomMapper;
use App\CustHub\Mapper\ChRoomMapper;
use App\CustHub\Model\ChRoomActiveRoom;
use Carbon\Carbon;
use Hyperf\Database\Model\Collection;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;
use function Hyperf\Collection\collect;

/**
 * 有效期
 */
class ChRoomActiveRoomService extends AbstractService
{
    public $mapper;

    #[Inject]
    protected ChOpSchemeMapper $schemeMapper;

    #[Inject]
    protected ChRoomMapper $roomMapper;

    public function __construct(ChRoomActiveRoomMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    public function saveHandle(array $schemeIds,array $robotIds,int $type)
    {
        switch ($type){
            case OpSchemeTypeConstants::ROOM_WELCOME:
                //入群欢迎语
                $this->roomWelcome($schemeIds,$robotIds,$type);
                break;
            default:
                break;
        }
    }

    /**
     * 删除生效群
     * @param array $schemeIds
     * @param array $robotIds
     * @param int $type
     * @return void
     * @throws \Exception
     */
    public function deleteHandle(array $schemeIds,array $robotIds,int $type): void
    {
        $activeRoomType = null;
        switch ($type){
            case OpSchemeTypeConstants::ROOM_WELCOME:
                //入群欢迎语
                $activeRoomType = RoomActiveRoomTypeConstants::ROOM_WELCOME_MESSAGE;
                break;
            default:
                break;
        }

        if(!is_null($activeRoomType)){
            $this->deleteActiveRoom($schemeIds,$robotIds,$activeRoomType);
        }
    }



    /**
     * 入群欢迎语
     * @param array $schemeIds
     * @param array $robotIds
     * @param int $type
     * @param int $activeRoomType
     * @return void
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function roomWelcome(array $schemeIds,array $robotIds,int $type): void
    {
        $schemeList = $this->getSchemeList($schemeIds,$type);

        foreach ($schemeList as $scheme){
            $matchRobotIds = [];
            $cfg = $scheme->cfg;
            $activeRoom = $cfg['active_room'];
            if($activeRoom['type'] == 1){
                //选择指定的群
                $roomWxidList = [];
                foreach ($activeRoom['room'] as $roomItem){
                    $robotId = $roomItem['robot_id'];
                    $matchRobotIds[] = $robotId;
                    $roomWxids = $roomItem['room_wxids'];
                    $roomWxids = array_map(function ($roomWxid) use ($robotId){
                        return [
                            'robot_id' => $robotId,
                            'room_wxid' => $roomWxid,
                        ];
                    },$roomWxids);
                    $roomWxidList = array_merge($roomWxidList,$roomWxids);
                }
            }elseif ($activeRoom['type'] == 2){
                $roomWxidList = [];
                foreach ($robotIds as $robotId){
                    $cond['robot_id'] = $robotId;
                    $cond['uid'] = $scheme->uid;
                    $cond['main_uid'] = $scheme->main_uid;
                    $matchRobotIds[] = $robotId;
                    $roomWxids = $this->roomMapper->getRoomWxids($cond);

                    $roomWxids = $roomWxids->map(function ($item) use ($robotId){
                        return [
                            'robot_id' => $robotId,
                            'room_wxid' => $item
                        ];
                    })->toArray();

                    $roomWxidList = array_merge($roomWxidList,$roomWxids);
                }
            }else{
                //所有群
                $roomList = $this->roomMapper->model::query()
                    ->select(['id','room_wxid'])
                    ->with(['robots' => function ($query) {
                        $query->select(['id']);
                    }])
                    ->where('main_uid',$scheme->main_uid)
                    ->get();
                $roomWxidList = [];
                foreach ($roomList as $item){
                    $robotRoomWxids = [];
                    foreach ($item->robots as $robot){
                        $matchRobotIds[] = $robot->id;
                        $robotRoomWxids[] = [
                            'robot_id' => $robot->id,
                            'room_wxid' => $item->room_wxid
                        ];
                    }
                    $roomWxidList = array_merge($roomWxidList,$robotRoomWxids);
                }
            }

            $existRobotIds = $this->mapper->model::query()
                ->where('scheme_id',$scheme->id)
                ->where('type',RoomActiveRoomTypeConstants::ROOM_WELCOME_MESSAGE)
                ->pluck('robot_id')
                ->toArray();
            $diff = array_diff($existRobotIds,$matchRobotIds);
            if(!empty($diff)){
                $this->mapper->model::query()
                    ->where('scheme_id',$scheme->id)
                    ->whereIn('robot_id',$diff)
                    ->where('type',RoomActiveRoomTypeConstants::ROOM_WELCOME_MESSAGE)
                    ->delete();
            }

            $uniqueRoomWxidList = uniqueArrayByField($roomWxidList,'room_wxid');

            $roomWxMap = [];
            foreach ($uniqueRoomWxidList as $item){
                $roomWxMap[$item['robot_id']][] = $item['room_wxid'];
            }
            foreach ($roomWxMap as $robotId => $item){
                $this->saveActiveRoom($scheme->id,(int)$robotId,$scheme->main_uid,$item,RoomActiveRoomTypeConstants::ROOM_WELCOME_MESSAGE);
            }
        }
    }

    /**
     * 智能标签-社群行为-生效群
     * @param int $id
     * @param int $uid
     * @param int $mainUid
     * @param array $rule
     * @return void
     */
    public function roomSmartTagRuleSave(int $id,int $uid,int $mainUid,array $rule): void
    {
        $rooms = $rule['room'];
        $roomWxidList = [];
        $robotIds = [];
        foreach ($rooms as $room){
            $robotId = $room['robot_id'];

            if($room['target_type'] == 0){
                $roomWxids = collect($room['room_wxids'])->map(function ($item) use ($robotId){
                    return [
                        'robot_id' => $robotId,
                        'room_wxid' => $item
                    ];
                })->toArray();
                $roomWxidList = array_merge($roomWxidList,$roomWxids);
                $robotIds[] = $robotId;
            }else{
                //按照标签筛选群
                $roomWxids = $this->roomMapper->getRoomWxids([
                    'uid' => $uid,
                    'main_uid' => $mainUid,
                    'robot_id' => $robotId,
                    'include_params' => [
                        'room_tag' => [
                            'match_type' => 1,
                            'ids' => $room['room_tag_ids']
                        ]
                    ]
                ]);
                $roomWxids = $roomWxids->map(function ($item) use ($robotId){
                    return [
                        'robot_id' => $robotId,
                        'room_wxid' => $item
                    ];
                })->toArray();
                if(!empty($roomWxids)){
                    $robotIds[] = $robotId;
                    $roomWxidList = array_merge($roomWxidList,$roomWxids);
                }
            }
        }

        $existRobotIds = $this->mapper->model::query()
            ->where('scheme_id',$id)
            ->where('type',RoomActiveRoomTypeConstants::SMART_TAG_GROUP_BEHAVIOR)
            ->pluck('robot_id')
            ->toArray();
        $diff = array_diff($existRobotIds,$robotIds);
        if(!empty($diff)){
            $this->mapper->model::query()
                ->where('scheme_id',$id)
                ->whereIn('robot_id',$diff)
                ->where('type',RoomActiveRoomTypeConstants::SMART_TAG_GROUP_BEHAVIOR)
                ->delete();
        }
        $uniqueRoomWxidList = uniqueArrayByField($roomWxidList,'room_wxid');
        $roomWxMap = [];
        foreach ($uniqueRoomWxidList as $item){
            $roomWxMap[$item['robot_id']][] = $item['room_wxid'];
        }
        foreach ($roomWxMap as $robotId => $item){
            $this->saveActiveRoom($id,(int)$robotId,$mainUid,$item,RoomActiveRoomTypeConstants::SMART_TAG_GROUP_BEHAVIOR);
        }
    }

    public function deleteActiveRoom(array $ids,array $robotIds,int $activeRoomType): void
    {
        $this->mapper->model::query()
            ->whereIn('scheme_id',$ids)
            ->when(!empty($robotIds),function ($query) use ($robotIds){
                $query->whereIn('robot_id',$robotIds);
            })
            ->where('type',$activeRoomType)
            ->delete();
    }

    /**
     * 保存生效群
     * @param int $schemeId
     * @param int $robotId
     * @param int $mainUid
     * @param array $roomWxidList
     * @param int $type
     * @return void
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function saveActiveRoom(int $schemeId,int $robotId,int $mainUid,array $roomWxidList,int $type)
    {
        //获取当前方案已配置的有效群
        $existingRoomWxids = $this->mapper->model::query()
            ->where('scheme_id',$schemeId)
            ->where('robot_id',$robotId)
            ->where('type',$type)
            ->pluck('room_wxid')
            ->toArray();

        $activeRooms = $this->mapper->findByRoomWxidsAndType($mainUid,$roomWxidList,$type);
        $activeRoomMap = $activeRooms->keyBy('room_wxid')->toArray();
        $toUpdate = [];
        $toInsert = [];
        $now = Carbon::now()->toDateTimeString();

        foreach ($roomWxidList as $roomWxid){
            if(isset($activeRoomMap[$roomWxid])){
                $activeRoom = $activeRoomMap[$roomWxid];
                if($activeRoom['scheme_id'] != $schemeId){
                    $toUpdate[] = [
                        'id' => $activeRoom['id'],
                        'scheme_id' => $schemeId,
                        'robot_id' => $robotId,
                        'updated_at' => $now
                    ];
                }
            }else{
                $toInsert[] = [
                    'main_uid' => $mainUid,
                    'scheme_id' => $schemeId,
                    'robot_id' => $robotId,
                    'room_wxid' => $roomWxid,
                    'type' => $type,
                    'created_at' => $now,
                    'updated_at' => $now,
                ];
            }
        }


        if(!empty($toUpdate)){
            container()->get(BatchUpdateService::class)->batchUpdate((new ChRoomActiveRoom())->getTable(), $toUpdate, ['id']);
        }

        if(!empty($toInsert)){
            $this->mapper->model::insert($toInsert);
        }

        $diffRoomWxids = array_diff($existingRoomWxids,$roomWxidList);
        if(!empty($diffRoomWxids)){
            $this->mapper->model::query()
                ->whereIn('room_wxid',$diffRoomWxids)
                ->where('scheme_id',$schemeId)
                ->where('type',$type)
                ->delete();
        }
    }

    /**
     * 获取方案列表
     * @param array $schemeIds
     * @param int $type
     * @return array|Collection|\Hyperf\Collection\Collection
     */
    private function getSchemeList(array $schemeIds,int $type): array|Collection|\Hyperf\Collection\Collection
    {
        $schemeList = $this->schemeMapper->model::query()
            ->select(['id','uid','main_uid','cfg'])
            ->whereIn('id',$schemeIds)
            ->where('type',$type)
            ->get();
        return $schemeList;
    }
}